<?php

declare(strict_types=1);
/**
 * This file is part of MoChat.
 * @link     https://mo.chat
 * @document https://mochat.wiki
 * @contact  group@mo.chat
 * @license  https://github.com/mochat-cloud/mochat/blob/master/LICENSE
 */
namespace MoChat\Plugin\ContactEmployeeTag\Service;

use MoChat\Framework\Service\AbstractService;
use MoChat\Plugin\ContactEmployeeTag\Contract\ContactEmployeeTagContract;
use MoChat\Plugin\ContactEmployeeTag\Model\ContactEmployeeTag;
use MoChat\Plugin\ContactEmployeeTag\Model\ContactEmployeeTagPivot;

class ContactEmployeeTagService extends AbstractService implements ContactEmployeeTagContract
{
    /**
     * @var ContactEmployeeTag
     */
    protected $model;

    /**
     * 查询单条 - 根据ID.
     * @param int $id ID
     * @param array|string[] $columns 查询字段
     * @return array 数组
     */
    public function getContactEmployeeTagById(int $id, array $columns = ['*']): array
    {
        return $this->model->getOneById($id, $columns);
    }

    /**
     * 查询多条 - 根据ID.
     * @param array $ids ID
     * @param array|string[] $columns 查询字段
     * @return array 数组
     */
    public function getContactEmployeeTagsById(array $ids, array $columns = ['*']): array
    {
        return $this->model->getAllById($ids, $columns);
    }

    /**
     * 多条分页.
     * @param array $where 查询条件
     * @param array|string[] $columns 查询字段
     * @param array $options 可选项 ['orderByRaw'=> 'id asc', 'perPage' => 15, 'page' => null, 'pageName' => 'page']
     * @return array 分页结果 Hyperf\Paginator\Paginator::toArray
     */
    public function getContactEmployeeTagList(array $where, array $columns = ['*'], array $options = []): array
    {
        return $this->model->getPageList($where, $columns, $options);
    }

    /**
     * 添加单条
     * @param array $data 添加的数据
     * @return int 自增ID
     */
    public function createContactEmployeeTag(array $data): int
    {
        return $this->model->createOne($data);
    }

    /**
     * 添加多条
     * @param array $data 添加的数据
     * @return bool 执行结果
     */
    public function createContactEmployeeTags(array $data): bool
    {
        return $this->model->createAll($data);
    }

    /**
     * 修改单条 - 根据ID.
     * @param int $id id
     * @param array $data 修改数据
     * @return int 修改条数
     */
    public function updateContactEmployeeTagById(int $id, array $data): int
    {
        return $this->model->updateOneById($id, $data);
    }

    /**
     * 修改多条
     */
    public function updateContactEmployeeTag(array $values): int
    {
        return $this->model->batchUpdateByIds($values);
    }

    /**
     * 修改多条 - 根据ID.
     * @param array $ids id
     * @param array $data 修改数据
     * @return int 修改条数
     */
    public function updateAllByIds(array $ids, array $data): int
    {
        return $this->model::query()
            ->whereIn('id', $ids)
            ->update($data);
    }

    /**
     * 删除 - 单条
     * @param int $id 删除ID
     * @return int 删除条数
     */
    public function deleteContactEmployeeTag(int $id): int
    {
        return $this->model->deleteOne($id);
    }

    /**
     * 删除 - 多条
     * @param array $ids 删除ID
     * @return int 删除条数
     */
    public function deleteContactEmployeeTags(array $ids): int
    {
        return $this->model->deleteAll($ids);
    }

    /**
     * 查询多条 - 根据标签名称.
     * @param string $name 标签名称
     * @param array|string[] $columns 查询字段
     * @return array 数组
     */
    public function getContactEmployeeTagsByName($name, array $columns = ['*']): array
    {
        $res = $this->model::query()
            ->where('name', $name)
            ->get($columns);

        if (empty($res)) {
            return [];
        }

        return $res->toArray();
    }

    /**
     * 修改单条 - 根据标签名称.
     * @param string $name 标签名称
     * @param array $data 修改数据
     * @return int 修改条数
     */
    public function updateContactEmployeeTagByName(string $name, array $data): int
    {
        return $this->model::query()
            ->where('name', $name)
            ->update($data);
    }

    /**
     * 查询多条 - 根据员工id.
     * @param int $employeeId 员工id
     * @param array|string[] $columns 查询字段
     * @return array 数组
     */
    public function getContactEmployeeTagsByEmployeeId(int $employeeId, array $columns = ['*']): array
    {
        $res = $this->model::query()
            ->where('employee_id', $employeeId)
            ->whereNull('deleted_at')
            ->get($columns);

        if (empty($res)) {
            return [];
        }

        return $res->toArray();
    }

    /**
     * 查询单条 - 根据员工id和标签名称.
     * @param string $name 标签名称
     * @param array $columns 查询字段
     * @return array 返回值
     */
    public function getContactEmployeeTagByEmployeeIdName(int $employeeId, string $name, array $columns = ['*']): array
    {
        $res = $this->model::query()
            ->where('employee_id', $employeeId)
            ->where('name', $name)
            ->first($columns);
        if (empty($res)) {
            return [];
        }

        return $res->toArray();
    }

    /**
     * 查询多条 - 根据ID（包括软删数据）.
     * @param array $ids ID
     * @param array|string[] $columns 查询字段
     * @return array 数组
     */
    public function getContactEmployeeTagsSoftById(array $ids, array $columns = ['*']): array
    {
        $res = $this->model::query()
            ->withTrashed()
            ->whereIn('id', $ids)
            ->get($columns);
        if (empty($res)) {
            return [];
        }

        return $res->toArray();
    }

    /**
     * 根据客户id查询多个员工个人客户标签(中间表).
     *
     * @param int $contactId ID
     * @param array|string[] $columns 查询字段
     *
     * @return array 数组
     */
    public function getContactEmployeeTagsByContactId(int $contactId, array $columns = ['*']): array
    {
        $res = ContactEmployeeTagPivot::query()
            ->where('contact_id', $contactId)
            ->get($columns);

        if (empty($res)) {
            return [];
        }

        return $res->toArray();
    }

    /**
     * 删除多条 根据客户id和员工id(中间表).
     * @param int $contactId 客户id
     * @return int 返回多条
     */
    public function deleteContactEmployeeTagsByContactIdEmployeeIdTagId(int $contactId, int $employeeId, array $tagId): int
    {
        return ContactEmployeeTagPivot::query()
            ->where('contact_id', $contactId)
            ->where('employee_id', $employeeId)
            ->whereIn('contact_tag_id', $tagId)
            ->delete();
    }

    /**
     * 给客户打个人标签，添加多条(中间表).
     * @param array $data 添加的数据
     *
     * @return bool 执行结果
     */
    public function createContactEmployeeTagToContact(array $data): bool
    {
        return (new ContactEmployeeTagPivot())->createAll($data);
    }

    /**
     * 根据客户id和员工id获取客户的个人标签.
     */
    public function getContactEmployeeTagsByContactIdEmployeeId(int $contactId, int $employeeId, array $columns = ['*']): array
    {
        $result = ContactEmployeeTagPivot::query()
            ->where('contact_id', $contactId);
        if ($employeeId > 0) {
            $result = $result->where('employee_id', $employeeId);
        }

        $result = $result->get(['contact_tag_id']);

        if ($result->isEmpty()) {
            return [];
        }

        $tagIds = array_column($result->toArray(), 'contactTagId');
        return $this->getContactEmployeeTagsById($tagIds, ['id', 'name']);
    }
}
